package com.crud.project.shrio;

import com.crud.project.dao.CustomRealm;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;

@Configuration
public class shrioConfig {
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager){
        //建立拦截器对象
        ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();
        //给拦截器对象把shrio管理工厂添加进来
        shiroFilterFactoryBean.setSecurityManager(securityManager);

        //设立拦截规则，给予地址和权限控制
        Map<String,String> filterChainDefinitionMap=new HashMap<String, String>();
        //anno配置不会被拦截的地址
        filterChainDefinitionMap.put("/login","anon");
        filterChainDefinitionMap.put("/loginChecked","anon");
        filterChainDefinitionMap.put("/statics/**","anon");
        filterChainDefinitionMap.put("/css/**","anon");
        filterChainDefinitionMap.put("/js/**","anon");
//        filterChainDefinitionMap.put("/js/**","anon");
        //authc配置拦截需要身份认证
        filterChainDefinitionMap.put("/**","authc");
        filterChainDefinitionMap.put("/first","authc");
        filterChainDefinitionMap.put("/second","authc");
        //设置默认起始页
        shiroFilterFactoryBean.setLoginUrl("/login");
        //把拦截规则加进去配置
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }

    //给拦截器设置安全器处理
    @Bean
    public SecurityManager securityManager(HashedCredentialsMatcher matcher){
        DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager();
        securityManager.setRealm(myShrioRealm(matcher));
        return securityManager;
    }
    //自定义安全处理器设置认证，权限
    @Bean
    public CustomRealm myShrioRealm(HashedCredentialsMatcher matcher) {
        //获取dao对象
        CustomRealm myShrioRealm=new CustomRealm();
        //把对象加密
        myShrioRealm.setCredentialsMatcher(matcher);
        return myShrioRealm;
    }
    //加密算法
    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher(){
        //构建一个加密对象，调用相对应的加密方式
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        // 采用MD5方式加密
        hashedCredentialsMatcher.setHashAlgorithmName("MD5");
        // 设置加密次数
        hashedCredentialsMatcher.setHashIterations(1);
        return hashedCredentialsMatcher;
    }

    /**
     *  开启Shiro的注解(如@RequiresRoles,@RequiresPermissions),需借助SpringAOP扫描使用Shiro注解的类,并在必要时进行安全逻辑验证
     * 配置以下两个bean(DefaultAdvisorAutoProxyCreator和AuthorizationAttributeSourceAdvisor)即可实现此功能
     * @return
     */
    @Bean
    public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        advisorAutoProxyCreator.setProxyTargetClass(true);
        return advisorAutoProxyCreator;
    }

    /**
     * 开启aop注解支持
     * @param securityManager
     * @return
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }


}
